In [14]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri
from functools import reduce
# import seaborn
from math import gamma
from operator import mul
In [31]:
corners = np.array([[0, 0], [1, 0], [0.5,0.75**0.5]])
print(corners)
triangle = tri.Triangulation(corners[:, 0], corners[:, 1])
In [32]:
refiner = tri.UniformTriRefiner(triangle)
trimesh = refiner.refine_triangulation(subdiv=4)
plt.figure(figsize=(10, 5))
for (i, shape) in enumerate((triangle, trimesh)):
plt.subplot(1, 2, i+ 1)
plt.triplot(shape)
plt.axis('off')
plt.axis('equal')
In [45]:
# Mid-points of triangle sides opposite of each corner
midpoints = []
for i in range(3):
point1 = corners[(i + 1) % 3]
point2 = corners[(i + 2) % 3]
mid = (point1 + point2) / 2.0
print(point1, '+', point2, '=', mid)
midpoints.append(mid)
print('\n')
print(midpoints)
In [34]:
def xy2bc(xy, tol=1.e-3):
'''Converts 2D Cartesian coordinates to barycentric.'''
s = [(corners[i] - midpoints[i]).dot(xy - midpoints[i]) / 0.75 for i in range(3)]
return np.clip(s, tol, 1.0 - tol)
Gamma: $\Gamma \left( z \right) = \int\limits_0^\infty {x^{z - 1} e^{ - x} dx}$
$ \text{Dir}\left(\boldsymbol{\alpha}\right)\rightarrow \mathrm{p}\left(\boldsymbol{\theta}\mid\boldsymbol{\alpha}\right)=\frac{\Gamma\left(\sum_{i=1}^{k}\boldsymbol{\alpha}_{i}\right)}{\prod_{i=1}^{k}\Gamma\left(\boldsymbol{\alpha}_{i}\right)}\prod_{i=1}^{k}\boldsymbol{\theta}_{i}^{\boldsymbol{\alpha}_{i}-1} \\ K\geq2\ \text{number of categories} \\ {\alpha _{1},\ldots ,\alpha _{K}}\ concentration\ parameters,\ where\ {\alpha_{i}>0} $
In [35]:
class Dirichlet(object):
def __init__(self, alpha):
self._alpha = np.array(alpha)
self._coef = gamma(np.sum(self._alpha)) / reduce(mul, [gamma(a) for a in self._alpha])
def pdf(self, x):
'''Returns pdf value for `x`.'''
return self._coef * reduce(mul, [xx ** (aa - 1) for (xx, aa)in zip(x, self._alpha)])
In [36]:
def draw_pdf_contours(dist, nlevels=200, subdiv=8, **kwargs):
import math
refiner = tri.UniformTriRefiner(triangle)
trimesh = refiner.refine_triangulation(subdiv=subdiv)
pvals = [dist.pdf(xy2bc(xy)) for xy in zip(trimesh.x, trimesh.y)]
plt.tricontourf(trimesh, pvals, nlevels, **kwargs)
plt.axis('equal')
plt.xlim(0, 1)
plt.ylim(0, 0.75**0.5)
plt.axis('off')
In [37]:
draw_pdf_contours(Dirichlet([1, 1, 1]))
In [38]:
draw_pdf_contours(Dirichlet([0.999, 0.999, 0.999]))
In [39]:
draw_pdf_contours(Dirichlet([5, 5, 5]))
In [48]:
draw_pdf_contours(Dirichlet([1, 2, 3]))
In [49]:
draw_pdf_contours(Dirichlet([3, 2, 1]))
In [50]:
draw_pdf_contours(Dirichlet([2, 3, 1]))
In [ ]: